<html>
<head><meta charset="utf-8"><title>can&#x27;t find specs for stacked borrows, reborrows · t-lang/doc · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/index.html">t-lang/doc</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html">can&#x27;t find specs for stacked borrows, reborrows</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="244806671"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/244806671" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#244806671">(Jul 03 2021 at 13:54)</a>:</h4>
<p>hi! i'm having trouble finding specifications for stacked borrows or reborrows. i think they're both stabilized in some form, but i can't find any obvious specifications in the Reference or in an RFC. am i missing something? or are we missing documentation for these?</p>



<a name="244806815"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/244806815" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#244806815">(Jul 03 2021 at 13:56)</a>:</h4>
<p>Stacked borrows is not stabilized. It is a proposal memory model for rust. We may or may not choose to adapt it unchanged or with changes. <a href="https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md">https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md</a> has some documentation.</p>



<a name="244806827"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/244806827" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#244806827">(Jul 03 2021 at 13:57)</a>:</h4>
<p>i should mention that lack of documentation for reborrows is already well known: <a href="https://github.com/rust-lang/reference/issues/788">https://github.com/rust-lang/reference/issues/788</a></p>



<a name="244806975"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/244806975" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#244806975">(Jul 03 2021 at 13:59)</a>:</h4>
<p>thanks. i think there's observable behavior of the borrow checker that isn't explained in any official documentation and partially conflicts with it, and stacked borrows are the closest explanation for the observed behavior. i think this isn't a great situation</p>



<a name="244807565"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/244807565" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#244807565">(Jul 03 2021 at 14:11)</a>:</h4>
<p>i'm not sure i understand. that page and some blog posts talk about stacked borrows being implemented. in what form is it implemented? i found <a href="https://github.com/rust-lang/rust/pull/55270">https://github.com/rust-lang/rust/pull/55270</a> that changes some MIR stuff; did it change any observable behavior in the borrow checker?</p>



<a name="244807624"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/244807624" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#244807624">(Jul 03 2021 at 14:12)</a>:</h4>
<p>or is stacked borrows an effort to formalize some currently undocumented behavior of the borrow checker?</p>



<a name="244807733"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/244807733" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#244807733">(Jul 03 2021 at 14:15)</a>:</h4>
<p>Stacked borrows is a memory model. It doesn't affect the borrow checked in any way. It only has an effect on what (unsafe) code you are allowed to write without causing UB and what optimizations are allowed. Miri checks if for a specific input to a program it doesn't violate stacked borrows. Stacked borrows (should) accept everything the borrow checker accepts and more. If you have <code>if some_function() { /* cause memory unsafety */ }</code> the borrow checker will reject it, while stacked borrows will accept it if <code>some_function()</code> evaluates to false.</p>



<a name="244808196"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/244808196" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#244808196">(Jul 03 2021 at 14:25)</a>:</h4>
<p>so is the current "implementation" limited to adding tooling to validate the conformance of unsafe code to the stacked borrows model?</p>



<a name="244808575"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/244808575" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#244808575">(Jul 03 2021 at 14:32)</a>:</h4>
<p>sorry, i'm at a stage of my learning where i can easily run into borrow checker behavior that isn't explained in the official documentation and appears to partially conflict with it. meanwhile, experts act like it's something that "everyone knows", but the best (partial) descriptions are all in blog posts and help threads, and those explanations also conflict with each other to some degree</p>



<a name="244808774"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/244808774" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#244808774">(Jul 03 2021 at 14:36)</a>:</h4>
<p>If you are not writing unsafe code you shouldn't worry about stacked borrows.</p>



<a name="244808790"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/244808790" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#244808790">(Jul 03 2021 at 14:36)</a>:</h4>
<p>What is the confusing behavior of the borrowchecker that you ran into?</p>



<a name="244809030"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/244809030" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#244809030">(Jul 03 2021 at 14:41)</a>:</h4>
<p>see <a href="https://github.com/rust-lang/reference/issues/788">https://github.com/rust-lang/reference/issues/788</a> for a few examples.<br>
basically it seems like "everybody knows" that you can reborrow a mutable reference as immutable or mutable with a different lifetime, but it's documented nowhere official (that i could find). the Book and the Reference at least strongly suggest that you can't have an immutable borrow of a value that's already mutably borrowed, and that you can't have multiple simultaneous mutable borrows of the same value. reborrows appear to violate those rules. there's other behavior changes introduced by NLL that are at least documented in the NLL RFC, but those would be easier to translate into updates to the official documentation</p>



<a name="244809104"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/244809104" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#244809104">(Jul 03 2021 at 14:42)</a>:</h4>
<p>but the privileged nature of reborrows with respect to the exclusivity of mutable references isn't directly documented in the NLL RFC either, at least that i could find</p>



<a name="244809136"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/244809136" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#244809136">(Jul 03 2021 at 14:43)</a>:</h4>
<p><span class="user-mention silent" data-user-id="411291">Taylor Yu [they/she]</span> <a href="#narrow/stream/237824-t-lang.2Fdoc/topic/can't.20find.20specs.20for.20stacked.20borrows.2C.20reborrows/near/244808196">said</a>:</p>
<blockquote>
<p>so is the current "implementation" limited to adding tooling to validate the conformance of unsafe code to the stacked borrows model?</p>
</blockquote>
<p>a complete stacked borrows implementation would be limited to how the compiler turns Rust code into LLVM IR, it would not involve any new borrow-checker behavior</p>



<a name="244809165"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/244809165" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#244809165">(Jul 03 2021 at 14:44)</a>:</h4>
<p>For the example you gave of</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="cp">#![allow(unused)]</span><span class="w"></span>
<span class="k">fn</span> <span class="nf">reborrow</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">mx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">x</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">rx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;*</span><span class="n">mx</span><span class="p">;</span><span class="w"> </span><span class="c1">// reborrow</span>
<span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="s">"{:?}"</span><span class="p">,</span><span class="w"> </span><span class="n">rx</span><span class="p">);</span><span class="w"> </span><span class="c1">// this would implicitly reborrow if given `mx` instead</span>
<span class="w">    </span><span class="o">*</span><span class="n">mx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="p">;</span><span class="w"> </span><span class="c1">// use here so the lifetime includes the creation of `rx`</span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>This is accepted because you derive a new immutable reference <code>rx</code> from the mutable reference <code>mx</code>. Once you use <code>mx</code> again, <code>rx</code> is invalidated as it was derived from <code>mx</code>.</p>



<a name="244809192"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/244809192" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#244809192">(Jul 03 2021 at 14:44)</a>:</h4>
<p>note that reborrowing wasn't introduced with NLL, it also happened before that</p>



<a name="244809212"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/244809212" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#244809212">(Jul 03 2021 at 14:45)</a>:</h4>
<p>for example, any method call on a mutable reference implicitly reborrows it, otherwise a single <code>&amp;mut</code> method call would consume the mutable reference</p>



<a name="244809445"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/244809445" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#244809445">(Jul 03 2021 at 14:51)</a>:</h4>
<p>thanks. that seems to fall into the hypothesis of "stacked borrows models existing underdocumented borrow checker behavior that occurs for safe code (primarily with respect to reborrows), and proposes additional formalization for the purpose of checking unsafe code". is that right?</p>



<a name="244847998"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/244847998" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#244847998">(Jul 04 2021 at 08:13)</a>:</h4>
<p>Stacked Borrows is all about unsafe code and compiler optimizations. I think you went down the wrong track there if your goal is understanding the borrow checker -- I don't think Stacked Borrows is the right way to understand the borrow checker.</p>



<a name="244848072"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/244848072" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#244848072">(Jul 04 2021 at 08:15)</a>:</h4>
<p><span class="user-mention silent" data-user-id="411291">Taylor Yu [they/she]</span> <a href="#narrow/stream/237824-t-lang.2Fdoc/topic/can't.20find.20specs.20for.20stacked.20borrows.2C.20reborrows/near/244809104">said</a>:</p>
<blockquote>
<p>but the privileged nature of reborrows with respect to the exclusivity of mutable references isn't directly documented in the NLL RFC either, at least that i could find</p>
</blockquote>
<p>hm, I don't think I ever though about it like that. when you have a local variable, you can create a shared reference to, well, share it -- temporarily:</p>
<div class="codehilite"><pre><span></span><code>let x = 5;
let y =&amp;x;
let z = &amp;x;
</code></pre></div>
<p>note that <code>x</code> is fully exclusively uniquely owned here, this is way stronger than a mutable reference! so if you find <code>&amp;mut → &amp;</code> surprising, this could be even more surprising?<br>
with mutabable references, you can likewise (temporarily) share them:</p>
<div class="codehilite"><pre><span></span><code>let x = &amp;mut 5;
let y = &amp;*x;
let z = &amp;*x;
</code></pre></div>



<a name="244848177"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/244848177" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#244848177">(Jul 04 2021 at 08:18)</a>:</h4>
<p>I think part of the problem here is that "you can't have an immutable borrow of a value that's already mutably borrowed" is a somewhat ambiguous statement... like, in some sense you <em>can</em> even have multiple mutable references to the same thing:</p>
<div class="codehilite"><pre><span></span><code>let x = &amp;mut 5;
let y = &amp;mut *x;
</code></pre></div>
<p>but this is okay since <code>x</code>  is "disabled" when <code>y</code> is created (technically: creating <code>y</code> means the compiler records a 'loan' for <code>x</code>, noting that <code>x</code> is currently "given away").<br>
What the rule "you can't have an immutable borrow of a value that's already mutably borrowed" really means is that you cannot have code like</p>
<div class="codehilite"><pre><span></span><code>let mut x = 5;
let y = &amp;mut x;
let z = &amp;x;
println!(&quot;{}&quot;, y);
</code></pre></div>
<p>IOW: you <em>can</em> have an "immutable (re)borrow of a mutable borrow" (that would be <code>let z = &amp;*x</code>), but you cannot have an "immutable borrow of a value with outstanding mutable loans" -- the rule you mentioned refers to the latter</p>



<a name="244863952"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/244863952" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#244863952">(Jul 04 2021 at 15:13)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/237824-t-lang.2Fdoc/topic/can't.20find.20specs.20for.20stacked.20borrows.2C.20reborrows/near/244847998">said</a>:</p>
<blockquote>
<p>Stacked Borrows is all about unsafe code and compiler optimizations. I think you went down the wrong track there if your goal is understanding the borrow checker -- I don't think Stacked Borrows is the right way to understand the borrow checker.</p>
</blockquote>
<p>thanks! i think it so happens that it provides a mental model to understand the borrow checker, because the invariants that Stacked Borrows tries to model happen to coincide with the invariants that the borrow checker enforces. (i think they should, because they're trying to achieve the same memory safety goals!)</p>
<p>i also think that there is no existing official documentation that communicates a good mental model for understanding the borrow checker nearly as well as Stacked Borrows does, and maybe we should fix that?</p>



<a name="244865278"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/244865278" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#244865278">(Jul 04 2021 at 15:47)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/237824-t-lang.2Fdoc/topic/can't.20find.20specs.20for.20stacked.20borrows.2C.20reborrows/near/244848177">said</a>:</p>
<blockquote>
<p>I think part of the problem here is that "you can't have an immutable borrow of a value that's already mutably borrowed" is a somewhat ambiguous statement... like, in some sense you <em>can</em> even have multiple mutable references to the same thing:</p>
<div class="codehilite"><pre><span></span><code>let x = &amp;mut 5;
let y = &amp;mut *x;
</code></pre></div>
<p>but this is okay since <code>x</code>  is "disabled" when <code>y</code> is created (technically: creating <code>y</code> means the compiler records a 'loan' for <code>x</code>, noting that <code>x</code> is currently "given away").</p>
</blockquote>
<p>but here, both <code>x</code> and <code>y</code> refer to the same memory location: the location of temporary value created in the <code>let x</code> statement. are borrows tracked per binding/reference, or per memory location? or per expression? this isn't clear to me from the existing official documentation. i guess it could be both: <code>x</code> is borrowed by <code>y</code>, so <code>x</code> is no longer a valid way to read or write that memory location until <code>y</code> is no longer live, which parallels the way that a direct borrow of a local variable binding suspends that binding until the direct borrow is no longer live.</p>
<p>(another frustrating ambiguity is whether "value" means "lvalue" or "rvalue" in any given usage)</p>
<p>it seems like <code>let y = &amp;mut *x</code> puts <code>x</code> itself into a borrowed state, making it inaccessible as long as <code>y</code> is live, even though by my reading of the semantics in the Reference and the Book, it should not. (<code>&amp;mut *x</code> is equivalent to (<code>&amp;mut (*x)</code>, right? so what's being borrowed is the mutable place expression <code>*x</code>, which is the same memory location as the temporary value.) i did notice that the NLL RFC gives some hints by mentioning "supporting prefixes", which specify a way that borrow expressions can transitively borrow subexpressions that constitute the place expression being borrowed, even though they're not direct operands of the borrow operator.</p>
<blockquote>
<p>What the rule "you can't have an immutable borrow of a value that's already mutably borrowed" really means is that you cannot have code like</p>
<div class="codehilite"><pre><span></span><code>let mut x = 5;
let y = &amp;mut x;
let z = &amp;x;
println!(&quot;{}&quot;, y);
</code></pre></div>
<p>IOW: you <em>can</em> have an "immutable (re)borrow of a mutable borrow" (that would be <code>let z = &amp;*x</code>), but you cannot have an "immutable borrow of a value with outstanding mutable loans" -- the rule you mentioned refers to the latter</p>
</blockquote>
<p>that seems to be two <em>direct</em> borrows of the local variable <code>x</code>, which is somehow distinct from two simultaneous borrows of the memory location bound by <code>x</code> in a way that i couldn't find good documentation about.</p>



<a name="244865579"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/244865579" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#244865579">(Jul 04 2021 at 15:55)</a>:</h4>
<p>would this be a correct summary of the memory safety invariants that both Stacked Borrows and the borrow checker try to enforce? "at any point in the control flow graph, there is at most one valid lvalue expression that can write to a given memory location. if such a valid write-enabled lvalue expression exists, then no lvalue expression that reads from that memory location can be valid at that point."</p>



<a name="244865653"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/244865653" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#244865653">(Jul 04 2021 at 15:57)</a>:</h4>
<blockquote>
<p><code>&amp;mut *x</code> is equivalent to <code>(&amp;mut (*x))</code></p>
</blockquote>
<p>The parens are only used by the parser, so <code>x</code> is not moved. What you meant was I think <code>&amp;mut {*x}</code>, which does move.<br>
In case of<code>&amp;mut {*x}</code> you have the place <code>*x</code>, which is turned into a value by <code>{*x}</code>. <code>&amp;mut</code> requires a place, so this value written to a temporary and then the <code>&amp;mut</code> takes a reference to this temporary. In case of <code>&amp;mut *x</code> you have a place <code>*x</code> to which a reference can directly be taken to. The place <code>*x</code> is recorded as being borrowed, which in turn disables <code>x</code>.</p>
<blockquote>
<p>so what's being borrowed is the mutable place expression *x, which is the same memory location as the temporary value.</p>
</blockquote>
<p>It may be impossible for the borrowchecker to know which memory location is borrowed. For example when passing in a reference. What happens is that <code>&amp;mut 5</code> disables the temporary containing <code>5</code> until the borrow ends. <code>&amp;mut *x</code> disables the local containing <code>x</code> until the borrow ends. <code>&amp;mut *x</code> does nothing to the original <code>5</code> temporary.</p>



<a name="244866008"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/244866008" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#244866008">(Jul 04 2021 at 16:06)</a>:</h4>
<blockquote>
<p>The parens are only used by the parser, so x is not moved. What you meant was I think &amp;mut {*x}, which does move.</p>
</blockquote>
<p>oh! so because block expressions can only return rvalues (i think?), the compiler can't short-circuit the borrow operator to use the memory location <code>*x</code>, and has to borrow a (moved or copied) temporary instead? (i'm pretty sure this short-circuiting happens in C with the unary <code>&amp;</code> address-of and <code>*</code> dereference operators, but i'm not sure the Reference explicitly explains how it works in Rust)</p>



<a name="244866061"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/244866061" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#244866061">(Jul 04 2021 at 16:08)</a>:</h4>
<blockquote>
<p>oh! so because block expressions can only return rvalues (i think?), the compiler can't short-circuit the borrow operator to use the memory location *x, and has to borrow a (moved or copied) temporary instead?</p>
</blockquote>
<p>Indeed</p>



<a name="244867407"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/244867407" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#244867407">(Jul 04 2021 at 16:45)</a>:</h4>
<blockquote>
<p>It may be impossible for the borrowchecker to know which memory location is borrowed.</p>
</blockquote>
<p>my understanding is that <em>in safe code</em>, tracking borrows of lvalues is sufficient to enforce memory safety invariants, so tracking borrows by memory location isn't necessary. the Stacked Borrows model (and the tracking per memory location that it describes) is useful for unsafe code because the compiler doesn't enforce the invariants on lvalues the same way it would in safe code. does that seem right?</p>



<a name="244867629"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/244867629" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#244867629">(Jul 04 2021 at 16:51)</a>:</h4>
<p>Yeah, I think that is the rough idea.</p>



<a name="245086322"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/245086322" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#245086322">(Jul 06 2021 at 19:19)</a>:</h4>
<p>looking back over this thread, i can only conclude "there is no specification for reborrow rules", except maybe for the compiler source code. is there something i'm missing? i couldn't find any RFC about reborrows.</p>



<a name="245089046"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/245089046" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#245089046">(Jul 06 2021 at 19:41)</a>:</h4>
<p>There isn't a specification for much of rust, to be fair. To be honest, I think stacked borrows gives a reasonable idea of the rules for static borrow checking, because it is a superset of those rules.</p>



<a name="245467969"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/245467969" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#245467969">(Jul 09 2021 at 16:53)</a>:</h4>
<blockquote>
<p>i think it so happens that it provides a mental model to understand the borrow checker, because the invariants that Stacked Borrows tries to model happen to coincide with the invariants that the borrow checker enforces. (i think they should, because they're trying to achieve the same memory safety goals!)</p>
</blockquote>
<p>oh, this is far from a coincidence. ;) Stacked Borrows was basically designed as "let's try to do borrow-checking at runtime".<br>
But I think you would be the first person to try to understand Stacked Borrows first, and the borrow checker based on that. On the other hand, if it works for you, sure.^^ Note however that Stacked Borrows is an <em>experiment</em>, not officially part of Rust. Also there are many different memory models that are all different but that are all compatible with the same borrow checker -- so it is impossible to learn the rules of the borrow checker by looking at the rules of the memory model.</p>
<blockquote>
<p>i also think that there is no existing official documentation that communicates a good mental model for understanding the borrow checker nearly as well as Stacked Borrows does</p>
</blockquote>
<p><span aria-label="heart" class="emoji emoji-2764" role="img" title="heart">:heart:</span> thanks for this -- I didnt expect the Stacked Borrows docs would ever be that useful.^^</p>



<a name="245468366"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/245468366" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#245468366">(Jul 09 2021 at 16:56)</a>:</h4>
<p><span class="user-mention silent" data-user-id="411291">Taylor Yu [they/she]</span> <a href="#narrow/stream/237824-t-lang.2Fdoc/topic/can't.20find.20specs.20for.20stacked.20borrows.2C.20reborrows/near/245086322">said</a>:</p>
<blockquote>
<p>looking back over this thread, i can only conclude "there is no specification for reborrow rules", except maybe for the compiler source code. is there something i'm missing? i couldn't find any RFC about reborrows.</p>
</blockquote>
<p>there's no precise <em>spec</em>, yes. there is lots of tutorial material and of course the playground to just "learn by doing", and I think that's how most of us pick up these rules. I certainly did. Heck, i designed Stacked Borrows based on that -- I never looked at the compiler source code for the borrow checker.</p>
<p>The rules are still changing (Polonius is coming, eventually), which might be a reason why there was not yet a concerted effort to precisely explain the <em>exact</em> rules. Most of us are okay with a somewhat vague mental model, and then interactively negotiating with the compiler until things work. you seem to be a different kind of person and I can see how that would make learning the borrow checker harder. sadly I don't really have a solution for you... :/</p>



<a name="245468578"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/245468578" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#245468578">(Jul 09 2021 at 16:57)</a>:</h4>
<p>i would hope that the Reference would document the subset of the rules that are well-established and haven't changed in a while, but it doesn't seem to have. so i guess i get to try to write some of that material for the Reference</p>



<a name="245468667"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/245468667" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#245468667">(Jul 09 2021 at 16:58)</a>:</h4>
<p>rules aren't monotone</p>



<a name="245468682"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/245468682" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#245468682">(Jul 09 2021 at 16:58)</a>:</h4>
<p>so, there's not really a "well-established subsets"</p>



<a name="245468747"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/245468747" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#245468747">(Jul 09 2021 at 16:59)</a>:</h4>
<p>there's enough that a fair number of experts seem to have a shared understanding, which happens to not be documented anywhere official</p>



<a name="245468760"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/245468760" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#245468760">(Jul 09 2021 at 16:59)</a>:</h4>
<p>you could try to precisely describe a simple borrow checker that accepts strictly less than the current one, but the full borrow checker won't be "just add more rules", it will be "use a totally different set of rules"</p>



<a name="245468824"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/245468824" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#245468824">(Jul 09 2021 at 16:59)</a>:</h4>
<p><span class="user-mention silent" data-user-id="411291">Taylor Yu [they/she]</span> <a href="#narrow/stream/237824-t-lang.2Fdoc/topic/can't.20find.20specs.20for.20stacked.20borrows.2C.20reborrows/near/245468747">said</a>:</p>
<blockquote>
<p>there's enough that a fair number of experts seem to have a shared understanding, which happens to not be documented anywhere official</p>
</blockquote>
<p>yes and we all got our understanding based on the docs you saw, and interacting with the compiler. some of us read the compiler sources, but I am fairly certainly the majority did not.</p>



<a name="245468938"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/245468938" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#245468938">(Jul 09 2021 at 17:00)</a>:</h4>
<p>and sadly, "understanding" is not something I can take out of my brain and into a file that I can share with you</p>



<a name="245468986"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/245468986" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#245468986">(Jul 09 2021 at 17:00)</a>:</h4>
<p>or rather, when I would try, it'd be like the Rust book and other tutorial material, that does not seem to be helpful for you</p>



<a name="245469110"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/245469110" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#245469110">(Jul 09 2021 at 17:01)</a>:</h4>
<p>however, having more material on the borrow checker in the reference would be great :)</p>



<a name="245469184"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/245469184" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#245469184">(Jul 09 2021 at 17:01)</a>:</h4>
<p>so if you want to help with that, that help would be very welcome!</p>



<a name="245469328"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/245469328" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#245469328">(Jul 09 2021 at 17:02)</a>:</h4>
<p>the Book should probably not contain all of these details. but maybe it should at least contain something like "these rules about references are simplified for ease of understanding. you might come across compiler behavior that appears to contradict these rules (reborrowing; NLL), but you should read the Reference to learn about how those work"</p>



<a name="245469349"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/245469349" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#245469349">(Jul 09 2021 at 17:02)</a>:</h4>
<p>there's a chance it might have to be rewritten when/if Polonius arrives, but it is still valuable -- Polonious isnt here yet, and having existing docs that need upgrading will also make it much easier to write the polonius docs</p>



<a name="245560203"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/237824-t-lang/doc/topic/can%27t%20find%20specs%20for%20stacked%20borrows%2C%20reborrows/near/245560203" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/237824-t-lang/doc/topic/can&#x27;t.20find.20specs.20for.20stacked.20borrows.2C.20reborrows.html#245560203">(Jul 10 2021 at 16:40)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/237824-t-lang.2Fdoc/topic/can't.20find.20specs.20for.20stacked.20borrows.2C.20reborrows/near/245468824">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="411291">Taylor Yu [they/she]</span> <a href="#narrow/stream/237824-t-lang.2Fdoc/topic/can't.20find.20specs.20for.20stacked.20borrows.2C.20reborrows/near/245468747">said</a>:</p>
<blockquote>
<p>there's enough that a fair number of experts seem to have a shared understanding, which happens to not be documented anywhere official</p>
</blockquote>
<p>yes and we all got our understanding based on the docs you saw, and interacting with the compiler. some of us read the compiler sources, but I am fairly certainly the majority did not.</p>
</blockquote>
<p>i think i saw that the Book and the Nomicon possibly used to have sections that covered reborrowing, but they don't currently. that might be part of the difficulties i ran into. the "Advanced borrowing" section of the older edition of the Book was deleted because it mostly dealt with writing kinds of explicit lifetime bounds that are no longer needed in modern Rust.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>